package com.alibaba.citrus.cr.mn.order.center.facade.service.impl;

import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.enums.ordercenter.AsyncMessageEventEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.ExchangeOrderTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderPushStatusEnum;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.lock.SaleRedisLock;
import com.alibaba.citrus.cr.mn.order.center.common.SetOrderTag;
import com.alibaba.citrus.cr.mn.order.center.common.util.TrimUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.*;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.ObtcSaleOrderLineIndexToResponseConvertor;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.obtcsaleorderlineindex.model.ObtcSaleOrderLineIndex;
import com.epoch.app.mnordercenter.exchangeorderatom.service.ExchangeOrderAtomService;
import com.epoch.app.mnordercenter.model.dto.*;
import com.epoch.app.mnordercenter.orderbaserequest.*;
import com.google.common.collect.Lists;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.mn.order.center.common.constants.RedisLockConstants.*;

/**
 * @author dongju
 * @ClassName ExchangeOrderAtomServiceImpl
 * @description: 换货订单原子服务
 * @date 2023/05/21
 * @version: 1.0
 **/
@Primary
@Component
public class ExchangeOrderAtomServiceImpl implements ExchangeOrderAtomService {
    private static final Log log = Log.getLogger(ExchangeOrderAtomServiceImpl.class);

    @Resource(name = "exchangeOrderAtomCreateService")
    private OrderAtomCreateService exchangeOrderAtomCreateService;
    @Resource(name = "exchangeOrderAtomUpdateService")
    private OrderAtomUpdateService exchangeOrderAtomUpdateService;
    @Resource(name = "exchangeOrderAtomSubmitService")
    private OrderAtomSubmitService exchangeOrderAtomSubmitService;
    @Resource(name = "exchangeOrderAtomCancelService")
    private OrderAtomCancelService exchangeOrderAtomCancelService;
    @Resource(name = "exchangeOrderAtomCloseService")
    private OrderAtomCloseService exchangeOrderAtomCloseService;
    @Resource(name = "exchangeOrderAtomQueryService")
    private OrderAtomQueryService<ExchangeOrderAtomQueryRequest, ExchangeOrderAtomBatchQueryRequest, ExchangeOrderAtomQueryResponse> exchangeOrderAtomQueryService;
    @Resource
    private SendMsgService sendMsgService;

    @FacadeInvoker(value = "批量创建换货订单", errorCode = "OC-03-001-01-16-006")
    @Override
    public Result<List<ExchangeOrderAtomCreateResponse>> batchCreate(ExchangeOrderAtomBatchCreateRequest request) {
        log.info("ExchangeOrderAtomServiceImpl#batchCreate request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ExchangeOrderAtomServiceImpl#batchCreate lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderAtomServiceImpl#batchCreate 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            // 移除入参里的前后空格
            TrimUtils.removeSpace(request);

            request.getOrderList().forEach(order -> {
                if (StringUtils.isNotBlank(request.getFromSys())) {
                    order.setFromSys(request.getFromSys());
                }
                if (StringUtils.isNotBlank(request.getBusinessType())) {
                    order.setBusinessType(request.getBusinessType());
                }
                if (StringUtils.isNotBlank(request.getBusinessUnitCode())) {
                    order.setBusinessUnitCode(request.getBusinessUnitCode());
                }
            });

            List<OrderAtomCreateResponse> resp = exchangeOrderAtomCreateService.batchCreate(request.getOrderList());
            List<OrderAtomCreateResponse> failList = resp.stream().filter(p -> StringUtils.isNotBlank(p.getErrorCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(failList)) {
                return Result.fail(convert(failList), "OC-01-001-01-16-006", "换货订单批量创建失败");
            }
            return Result.success(convert(resp), "", "");
        } catch (Exception e) {
            log.error("ExchangeOrderAtomServiceImpl#batchCreate error", e);
            throw e;
        }
    }

    private List<ExchangeOrderAtomCreateResponse> convert(List<OrderAtomCreateResponse> responseList) {

        return Optional.of(responseList).orElse(Lists.newArrayList()).stream().map(p -> {
            ExchangeOrderAtomCreateResponse createResponse = new ExchangeOrderAtomCreateResponse();
            createResponse.setOrderDetails(p.getOrderDetails());
            createResponse.setErrorCode(p.getErrorCode());
            createResponse.setMessage(p.getMessage());
            createResponse.setSalesOrderNo(p.getSalesOrderNo());
            createResponse.setSourceOrderNo(p.getSourceOrderNo());
            return createResponse;
        }).collect(Collectors.toList());
    }

    @FacadeInvoker(value = "批量关闭换货订单", errorCode = "OC-03-001-01-16-013")
    @Override
    public Result<List<OrderAtomCloseResponse>> batchClose(OrderAtomBatchCloseRequest request) {
        log.info("ExchangeOrderAtomServiceImpl#batchClose request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ExchangeOrderAtomServiceImpl#batchClose lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderAtomServiceImpl#batchClose 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            List<OrderAtomCloseResponse> closeResponses = exchangeOrderAtomCloseService.batchClose(request);
            if (CollectionUtils.isNotEmpty(closeResponses)) {
                // 发送消息通知来源系统
                List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = new ArrayList<>();
                for (OrderAtomCloseResponse closeResponse : closeResponses) {
                    if (Boolean.TRUE.equals(closeResponse.getSuccess())) {
                        // 成功的不发kafka消息，要基于sap关闭回调结果发kafka消息
                        continue;
                    }
                    pushOrderInfoList.add(PushOrderInfoToMnSideRequestOrderInfo.builder()
                            .salesOrderNo(closeResponse.getSalesOrderNo())
                            .lineNum(closeResponse.getLineNum())
                            .orderStatus(SalesOrderPushStatusEnum.FAIL_REFUSED.getOrderStatusCode())
                            .message(closeResponse.getMessage())
                            .build());
                }
                // 发送kafka消息通知应用端处理结果
//                sendMsgService.sendMsgToNYK(pushOrderInfoList);
                CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
                commonAsyncMessageResponse.setEventCode(AsyncMessageEventEnum.EXCHANGE_ORDER_REFUSED.getValue());
                commonAsyncMessageResponse.setEventName(AsyncMessageEventEnum.EXCHANGE_ORDER_REFUSED.getLabel());
                commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
                commonAsyncMessageResponse.setFromSys(request.getOrderList().get(0).getFromSys());
                commonAsyncMessageResponse.setBusinessUnitCode(request.getOrderList().get(0).getBusinessUnitCode());
                commonAsyncMessageResponse.setData(pushOrderInfoList);
                sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
                log.info("ExchangeOrderAtomServiceImpl#batchClose sendMsgToSendKafka message={}", commonAsyncMessageResponse);
            }
        } catch (FunctionException e) {
            log.error("ExchangeOrderAtomServiceImpl#batchClose FunctionException error", e);
            throw e;
        } catch (Exception e) {
            log.error("ExchangeOrderAtomServiceImpl#batchClose Exception error", e);
            throw e;
        }
        return Result.success(Lists.newArrayList(), "", "");
    }

    @FacadeInvoker(value = "更新换货订单", errorCode = "OC-03-001-01-16-014")
    @Override
    public Result<OrderAtomUpdateResponse> update(OrderAtomUpdateRequest request) {
        log.info("ExchangeOrderAtomServiceImpl#update request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_ATOM_PREFIX + request.getSalesOrderNo();
        log.info("ExchangeOrderAtomServiceImpl#update lockKey={}", lockKey);
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderAtomServiceImpl#update 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }
            OrderAtomUpdateResponse response = exchangeOrderAtomUpdateService.update(request);
            if(StringUtils.isNotBlank(response.getErrorCode())){
                return Result.fail(response, "", "");
            }
            return Result.success(response, "", "");
        } catch (Exception e) {
            log.error("ExchangeOrderAtomServiceImpl#update error", e);
            throw e;
        }
    }

    @FacadeInvoker(value = "批量取消换货订单", errorCode = "OC-03-001-01-16-015")
    @Override
    public Result<List<OrderAtomCancelResponse>> batchCancel(OrderAtomBatchCancelRequest request) {
        log.info("ExchangeOrderAtomServiceImpl#batchCancel request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ExchangeOrderAtomServiceImpl#batchCancel lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderAtomServiceImpl#batchCancel 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }
            List<OrderAtomCancelResponse> resp = exchangeOrderAtomCancelService.batchCancel(request);
            return Result.success(resp, "", "");
        } catch (Exception e) {
            log.error("ExchangeOrderAtomServiceImpl#batchCancel error", e);
            throw e;
        }
    }

    @FacadeInvoker(value = "批量提交换货订单", errorCode = "OC-03-001-01-16-006")
    @Override
    public Result<List<OrderAtomSubmitResponse>> batchSubmit(OrderAtomBatchSubmitRequest request) {
        log.info("ExchangeOrderAtomServiceImpl#batchSubmit request={}", JSON.toJSONString(request));
        String lockKey = EXCHANGE_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ExchangeOrderAtomServiceImpl#batchSubmit lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ExchangeOrderAtomServiceImpl#batchSubmit 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }
            log.error("ExchangeOrderAtomServiceImpl#batchSubmit request={}", JSONObject.toJSONString(request));

            request.getOrderList().forEach(order -> {
                if (StringUtils.isNotBlank(request.getFromSys())) {
                    order.setFromSys(request.getFromSys());
                }
                if (StringUtils.isNotBlank(request.getBusinessType())) {
                    order.setBusinessType(request.getBusinessType());
                }
                if (StringUtils.isNotBlank(request.getBusinessUnitCode())) {
                    order.setBusinessUnitCode(request.getBusinessUnitCode());
                }
            });
            List<OrderAtomSubmitResponse> submitResponses = exchangeOrderAtomSubmitService.batchSubmit(request.getOrderList());

            if (CollectionUtils.isNotEmpty(submitResponses)) {
                // 发送消息通知来源系统
                List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = new ArrayList<>();
                for (OrderAtomSubmitResponse submitResponse : submitResponses) {
                    pushOrderInfoList.add(PushOrderInfoToMnSideRequestOrderInfo.builder()
                            .salesOrderNo(submitResponse.getSalesOrderNo())
                            .orderStatus(SalesOrderPushStatusEnum.FAIL_UPDATE.getOrderStatusCode())
                            .message(submitResponse.getMessage())
                            .build());
                }
                // 发送kafka消息通知应用端处理结果
//                sendMsgService.sendMsgToNYK(pushOrderInfoList);
                CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
                commonAsyncMessageResponse.setEventCode(AsyncMessageEventEnum.EXCHANGE_ORDER_UPDATE.getValue());
                commonAsyncMessageResponse.setEventName(AsyncMessageEventEnum.EXCHANGE_ORDER_UPDATE.getLabel());
                commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
                commonAsyncMessageResponse.setFromSys(request.getOrderList().get(0).getFromSys());
                commonAsyncMessageResponse.setBusinessUnitCode(request.getOrderList().get(0).getBusinessUnitCode());
                commonAsyncMessageResponse.setData(pushOrderInfoList);
                sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
                log.info("ExchangeOrderAtomServiceImpl#batchSubmit sendMsgToSendKafka message={}", commonAsyncMessageResponse);
            }
            return Result.success(submitResponses, "", "");
        } catch (Exception e) {
            log.error("ExchangeOrderAtomServiceImpl#batchSubmit error", e);
            throw e;
        }
    }

    @FacadeInvoker(value = "订单精准查询", errorCode = "OC-01-003-01-16-008")
    @Override
    public Result<List<ExchangeOrderAtomQueryResponse>> query(ExchangeOrderAtomQueryRequest exchangeOrderAtomQueryRequest) {
        PageResult<List<ExchangeOrderAtomQueryResponse>> result = exchangeOrderAtomQueryService.listPage(exchangeOrderAtomQueryRequest);
        Result<List<ExchangeOrderAtomQueryResponse>> success = Result.success(result.getContent(), "", "");
        success.setTotal(result.getTotal());
        return success;
    }

    @FacadeInvoker(value = "订单批量查询", errorCode = "OC-01-003-01-16-008")
    @Override
    public Result<List<ExchangeOrderAtomQueryResponse>> batchQuery(ExchangeOrderAtomBatchQueryRequest exchangeOrderAtomBatchQueryRequest) {
        List<String> salesOrderType = exchangeOrderAtomBatchQueryRequest.getSalesOrderType();
        if (CollectionUtils.isEmpty(salesOrderType)) {
            exchangeOrderAtomBatchQueryRequest.setSalesOrderType(ExchangeOrderTypeEnum.codes());
        } else {
            salesOrderType.forEach(tmpSalesOrderType -> {
                if (Objects.isNull(ExchangeOrderTypeEnum.of(tmpSalesOrderType))) {
                    throw new FunctionException("OC-01-001-01-16-027");
                }
            });
        }
        exchangeOrderAtomBatchQueryRequest.setOrderCategoryCode(OrderCategoryEnum.COMPANY.getCode());
        PageResult<List<ExchangeOrderAtomQueryResponse>> result = exchangeOrderAtomQueryService.page(exchangeOrderAtomBatchQueryRequest, SetOrderTag.EXCHANGE);
        Result<List<ExchangeOrderAtomQueryResponse>> success = Result.success(result.getContent(), "", "");
        success.setTotal(result.getTotal());
        return success;
    }

    /**
     * 明细查询
     */
    @FacadeInvoker(value = "明细查询", errorCode = "OC-01-003-01-16-008")
    @Override
    public Result<List<ExchangeOrderQueryDetailResponse>> loadDetailForPage(ExchangeOrderAtomBatchQueryRequest exchangeOrderAtomBatchQueryRequest) {
        List<String> salesOrderType = exchangeOrderAtomBatchQueryRequest.getSalesOrderType();
        if (CollectionUtils.isEmpty(salesOrderType)) {
            exchangeOrderAtomBatchQueryRequest.setSalesOrderType(ExchangeOrderTypeEnum.codes());
        } else {
            salesOrderType.forEach(tmpSalesOrderType -> {
                if (Objects.isNull(ExchangeOrderTypeEnum.of(tmpSalesOrderType))) {
                    throw new FunctionException("OC-01-001-01-16-027");
                }
            });
        }
        exchangeOrderAtomBatchQueryRequest.setOrderCategoryCode(OrderCategoryEnum.COMPANY.getCode());
        Result<List<ObtcSaleOrderLineIndex>> listResult = exchangeOrderAtomQueryService.detailListPage(exchangeOrderAtomBatchQueryRequest);
        List<ExchangeOrderQueryDetailResponse> response = ObtcSaleOrderLineIndexToResponseConvertor.convertExchangeOrderQueryDetailResponse(listResult);
        Result<List<ExchangeOrderQueryDetailResponse>> success = Result.success(response, "", "");
        success.setTotal(listResult.getTotal());
        return success;
    }
}
